package ray_tracer;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;

import javax.swing.JFrame;

import object.Sphere;
import object.Triangle;

import ray.CameraRay;
import scene.Scene;
import screen.ScreenBuffer;
import util.Point3D;

public class RayTracer {

	private ScreenBuffer buffer;
	private JFrame frame;

	public RayTracer() {
		this.buffer = new ScreenBuffer();
		this.frame = new JFrame("Ray Tracer - Assignment 2");

		this.frame.setSize((int) ScreenBuffer.SCREEN.getWidth() + 10,
				(int) ScreenBuffer.SCREEN.getHeight() + 10);
		this.frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
	}

	public void buildScene() {
		// Create spheres
		Sphere largeSphere = new Sphere(new Point3D(0.05f, 0.0f, 0.0f), 0.33f,
				Color.RED);
		Sphere smallSphere = new Sphere(new Point3D(-0.4f, -0.15f, -0.5f),
				0.3f, Color.GREEN);
		// Create Triangles for floor
		Triangle tLeft = new Triangle(new Point3D(-3.0f, -0.7f, 1.0f),
				new Point3D(1.0f, -0.7f, 1.0f), new Point3D(-3.0f, -0.7f,
						-10.0f), Color.BLUE);
		Triangle tRight = new Triangle(new Point3D(1.0f, -0.7f, 1.0f),
				new Point3D(1.0f, -0.7f, -10.0f), new Point3D(-3.0f, -0.7f,
						-10.0f), Color.BLUE);
		// Add objects to scene
		Scene.getInstance().addSceneObject(tLeft);
		Scene.getInstance().addSceneObject(tRight);
		Scene.getInstance().addSceneObject(largeSphere);
		Scene.getInstance().addSceneObject(smallSphere);
	}

	public void renderScene(boolean useSuperSampling) {
		this.sample(Camera.NO_SHIFT);
		if (useSuperSampling) {
			this.sample(Camera.SHIFT_LEFT);
			this.sample(Camera.SHIFT_DOWN);
			this.sample(Camera.SHIFT_RIGHT);
			this.sample(Camera.SHIFT_UP);
		}
		frame.setVisible(true);
		buffer.draw((Graphics2D) frame.getGraphics());
	}

	private void sample(Rectangle2D shift) {
		CameraRay r;
		Scene.getInstance().getCamera().reset();
		Scene.getInstance().getCamera().setShift(shift);
		while (Scene.getInstance().getCamera().hasNextCameraRay()) {
			r = Scene.getInstance().getCamera().getNextCameraRay();
			buffer.addColorToPixel(r.getCorrespondingPixel(), r.getColor());
		}
	}

	public static void main(String[] args) {
		RayTracer tracer = new RayTracer();
		tracer.buildScene();
		tracer.renderScene(false);
	}

}
